package main

import (
	"sync"
)

// _queue 用于存储等待的goroutine
type _queue struct {
	cond     *sync.Cond
	data     []interface{}
	capacity int
}

// _newQueue 初始化函数
func _newQueue(capacity int) *_queue {
	return &_queue{
		// sync.NewCond(&sync.Mutex{}): 创建一个条件变量，绑定一个互斥锁（sync.Mutex）。sync.Cond 需要一个 Locker（通常是 sync.Mutex）来保护共享资源
		cond:     sync.NewCond(&sync.Mutex{}),
		capacity: capacity,
		data:     make([]interface{}, 0, capacity),
	}
}

// _enqueue 入队方法
func (q *_queue) _enqueue(item interface{}) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	// 队列已满 等待出队
	for len(q.data) == q.capacity {
		q.cond.Wait()
	}

	// 添加数据
	q.data = append(q.data, item)

	q.cond.Signal()
}

// _dequeue 出队方法
func (q *_queue) _dequeue() interface{} {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	// 队列为空 等待入队
	for len(q.data) == 0 {
		q.cond.Wait()
	}

	item := q.data[0]
	q.data = q.data[1:]

	// 通知等待的生产者
	q.cond.Signal()

	return item
}

//func main() {
//	queue := _newQueue(3)
//	var wg sync.WaitGroup
//
//	wg.Add(1)
//	go func() {
//		defer wg.Done()
//		for i := 0; i < 5; i++ {
//			queue._enqueue(i)
//			fmt.Printf("Produced:%d\n", i)
//			time.Sleep(100 * time.Millisecond)
//		}
//	}()
//	// 消费者
//	wg.Add(1)
//	go func() {
//		defer wg.Done()
//		for i := 0; i < 5; i++ {
//			item := queue._dequeue()
//			fmt.Printf("Consumed: %v\n", item)
//			time.Sleep(200 * time.Millisecond)
//		}
//	}()
//
//	wg.Wait()
//}
